#include <iostream>
#include <fstream>
#include <string>
#include <cstring>

#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

int main()
{
    // 创建 TCP 套接字（IPv4协议，流式套接字）
    int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_sock < 0) 
    {
        cerr << "socket error!" << endl;
        return 1;
    }

    // 配置服务器地址结构
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;         // IPv4 地址族
    local.sin_port = htons(8888);       // 绑定端口 8888（主机字节序转网络字节序）
    local.sin_addr.s_addr = htonl(INADDR_ANY);  // 绑定所有可用网络接口

    // 将套接字与地址绑定
    if (bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0) 
    {
        cerr << "bind error!" << endl;
        return 2;
    }

    // 开始监听连接请求，最大等待队列长度为5
    if (listen(listen_sock, 5) < 0) 
    {
        cerr << "listen error!" << endl;
        return 3;
    }

    // 主循环持续接受客户端连接
    struct sockaddr peer;
    memset(&peer, 0, sizeof(peer));
    socklen_t len = sizeof(peer);
    for (;;) 
    {
        // 接受新连接，生成用于通信的套接字
        int sock = accept(listen_sock, (struct sockaddr*)&peer, &len);
        if (sock < 0) 
        {
            cerr << "accept error!" << endl;
            continue;  // 跳过本次错误，继续监听
        }

        // 创建子进程处理请求（第一层 fork）
        if (fork() == 0) 
        {  
            // 子进程代码区域
            close(listen_sock);  // 子进程不需要监听套接字

            // 第二次 fork 创建孙子进程（避免僵尸进程）
            if (fork() > 0) 
            {  
                // 父进程（即第一层子进程）立即退出
                exit(0);
            }

            /* 孙子进程代码区域（由 init 进程接管）*/
            char buffer[1024];
            // 读取客户端发送的 HTTP 请求（未处理完整数据）
            recv(sock, buffer, sizeof(buffer), 0);  

            // 打印原始 HTTP 请求内容
            cout << "--------------------------http request begin--------------------------" << endl;
            cout << buffer << endl;
            cout << "---------------------------http request end---------------------------" << endl;

            close(sock);    // 关闭通信套接字
            exit(0);        // 孙子进程退出
        }

        // 主进程（爷爷进程）代码区域
        close(sock);  // 主进程不需要通信套接字

        // 等待所有子进程结束（回收第一层子进程）
        waitpid(-1, nullptr, 0);  
    }

    return 0;
}